package com.learn.singleton001;

import com.learn.util.PrintUtil;

import java.util.concurrent.TimeUnit;

/**
 *  测试
 * @author 1
 */
public class SingleObjectNotSafeTest {

    public static void main(String[] args) {

        /**
         * 小明： 线程不安全，我不相信呀。
         * 老王： 你看下面的代码，我创建了3个线程，发现几乎每个线程输出的地址都不一样
         * 小明： 咦~，还真是的。这是为啥呢？
         * 老王： 这是因为，很多线程同时执行的时候，判断 instance == null 的条件都满足，这样大家都进行new创建操作。这部乱套了。
         * 小明： 好吧。。。
         */
        for(int i = 0;i<3;i++){
            new Thread(()->{
                System.out.println(SingleObjectNotSafe.getInstance());
            }).start();
        }
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        PrintUtil.printLine();
        /**
         * 小明：下面的代码编译报错，这是为啥呢？
         * 老王： private 修饰的成员变量只能在类内部访问，所以这个构造方法不能访问。
         * 小明： 好吧。。。
         */
//        SingleObjectNotSafe singleObjectNotSafe = new SingleObjectNotSafe();

        /**
         * 小明： 我们不能通过new来创建实例对象了，呜呜呜
         * 老王： 通过调用下面的方法来创建实例对象。
         * 小明： 好吧。。。
         */
        SingleObjectNotSafe singleObjectNotSafe = SingleObjectNotSafe.getInstance();

        /**
         * 小明： 有来实例对象，我们可以干点啥坏事呢？嘿嘿嘿
         * 老王： 简单的数据一句话吧。
         * 小明： 好吧。。。
         */
        singleObjectNotSafe.showMessage();
        PrintUtil.printLine();
        /**
         * 小明： 我想创建一个实例
         * 老王： 那就来吧
         */
        SingleObjectNotSafe singleObjectNotSafe1 = SingleObjectNotSafe.getInstance();
        /**
         * 小明： 我还想创建一个实例
         * 老王： 那就来吧
         */
        SingleObjectNotSafe singleObjectNotSafe2 = SingleObjectNotSafe.getInstance();
        /**
         * 小明： 这两个实例，是同一哥实例吗？
         * 老王： 你觉得呢？
         * 小明： 我觉得是同一个，都在当前主线程创建的。应该是安全的。
         * 老王： 嗯，挺聪明的嘛！运行下看看
         * 小明： 我哇！！！返回true ，我懂了。
         */
        System.out.println(singleObjectNotSafe1 == singleObjectNotSafe2);
        PrintUtil.printLine();
        /**
         * 小明： 这两个是的的hashCode应该也是一样的吧？
         * 老王： 肯定了，都是同一个对象。再说这种蠢话，我就打你了。
         * 小明： 好吧。。。
         */
        System.out.println("实例1的hashCode："+singleObjectNotSafe1.hashCode() + "，实例2的hashCode："+singleObjectNotSafe2.hashCode());
        PrintUtil.printLine();


    }
}
